/*
 * Copyright (c) 2005, 2014 vacoor
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package org.vacoor.nothing.misc.dts.oo.comp;

import com.sun.star.beans.PropertyValue;
import com.sun.star.frame.XComponentLoader;
import com.sun.star.frame.XStorable;
import com.sun.star.lang.IllegalArgumentException;
import com.sun.star.lang.XComponent;
import com.sun.star.lib.uno.adapter.OutputStreamToXOutputStreamAdapter;
import org.vacoor.nothing.misc.dts.oo.io.SeekableInputStream;
import org.vacoor.nothing.misc.dts.oo.io.SeekableInputStreamToXSeekableInputStreamAdapter;
import org.vacoor.nothing.misc.dts.oo.util.UnoUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

/**
 * UNO 读写
 *
 * @author vacoor
 * @see <decode href="http://www.openoffice.org/api/docs/common/ref/com/sun/star/document/MediaDescriptor.html">OOo MediaDescriptor</decode>
 */
public abstract class UnoReadWriteSupport {

    protected XComponent loadForm(XComponentLoader xCompLoader, File source, PropertyValue[] propertyValues) throws IOException, IllegalArgumentException, IOException, IllegalArgumentException, com.sun.star.io.IOException {
        if (!source.exists() || !source.canRead()) {
            // TODO
        }
        // return loadForm(xCompLoader, new SeekableFileInputStream(source), propertyValues);
        // TODO file:///c:/   ?? file:///opt??
        return loadForm(xCompLoader, "file:///" + source.getAbsolutePath().replace("\\", "/"), propertyValues);
    }

    /**
     * 过时发现效率太低, 比 file:///home/vacoor/user.xls 效率低太多
     *
     * @deprecated
     */
    protected XComponent loadForm(XComponentLoader xCompLoader, SeekableInputStream source, PropertyValue[] propertyValues) throws com.sun.star.io.IOException, IllegalArgumentException {
        return loadForm(
                xCompLoader,
                "private:stream",
                UnoUtils.of(propertyValues, UnoUtils.of("InputStream", new SeekableInputStreamToXSeekableInputStreamAdapter(source)))
        );
    }

    /**
     * 不建议使用, 注意当 URL 对应文件不存在时不会报错, 会一直阻塞, 以后查找原因
     *
     * @param xCompLoader
     * @param url
     * @param propertyValues
     * @return
     */
    protected XComponent loadForm(XComponentLoader xCompLoader, String url, PropertyValue[] propertyValues) throws com.sun.star.io.IOException, IllegalArgumentException {
        return xCompLoader.loadComponentFromURL(url, "_blank", 0, propertyValues);
    }

    // --------------- store

    protected void storeTo(XStorable xStorable, File destination, PropertyValue[] propertyValues) throws IOException, com.sun.star.io.IOException {
        storeTo(xStorable, new FileOutputStream(destination), propertyValues);
    }

    /**
     * 将给定的 XStorable 使用给定的 properties 存储到给定的输出流
     */
    protected void storeTo(XStorable xStorable, OutputStream destination, PropertyValue[] propertyValues) throws com.sun.star.io.IOException, IOException {
        storeTo(
                xStorable,
                "private:stream",
                UnoUtils.of(propertyValues, UnoUtils.of("OutputStream", new OutputStreamToXOutputStreamAdapter(destination)))
        );
    }

    /**
     * 将给定 xStorable 存储到给定的 URL
     * <p/>
     * 注意: 对于文件系统 URL 使用 file:/// 开头, 而 java 是 file:/ 开头, 需要自行转换(eg: file:///opt --> file:///opt)
     * URL 对应路径如果不存在会自动创建所需路径
     * <p/>
     * <strong>建议使用以下两个方法</strong>:
     * {@link #storeTo(com.sun.star.frame.XStorable, java.io.OutputStream, com.sun.star.beans.PropertyValue[])}
     * {@link #storeTo(com.sun.star.frame.XStorable, java.io.File, com.sun.star.beans.PropertyValue[])}
     *
     * @param xStorable
     * @param url            存储的目的 URL
     * @param propertyValues 存储时使用的属性
     */
    protected void storeTo(XStorable xStorable, String url, PropertyValue[] propertyValues) throws IOException, com.sun.star.io.IOException {
        xStorable.storeToURL(url, propertyValues);
    }
}
